bitkeeper revision 1.570 (3fab8343LyJPc2KVRZYbCwAIS3T15g)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 7 Nov 2003 11:34:27 +0000 (11:34 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 7 Nov 2003 11:34:27 +0000 (11:34 +0000)
Many files:
  Various cleanups and fixes for suspend/resume. Just a couple more bugs to fix.

tools/internal/xi_build.c
tools/internal/xi_restore_linux.c
tools/internal/xi_save_linux.c
xen/arch/i386/mm.c
xen/arch/i386/process.c
xen/arch/i386/traps.c
xen/common/memory.c
xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c
xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h

index 0bc1f1299c29af282d3017acca3eb52669a0cbe3..0685d723bf66562ff39c756b0cffa02023b02434 100644 (file)
@@ -461,7 +461,10 @@ int main(int argc, char **argv)
                        load_addr, ksize, &launch_op.u.builddomain,
                        argc, argv, args_start, 
                        op.u.getdomaininfo.shared_info_frame) < 0 )
+    {
+        ERROR("Error constructing guest OS");
         return 1;
+    }
 
     if ( initrd_fd >= 0 )
         close(initrd_fd);
index 0e2aebd9c4e362d285da7a4a600d7aa6a28e7a03..bd42e62952d2e5c1adffa541cb0a0085fa339f08 100644 (file)
@@ -42,12 +42,13 @@ static int get_pfn_list(
 static mmu_update_t mmu_updates[MAX_MMU_UPDATES];
 static int mmu_update_idx;
 
-static void flush_mmu_updates(void)
+static int flush_mmu_updates(void)
 {
+    int err = 0;
     privcmd_hypercall_t hypercall;
 
     if ( mmu_update_idx == 0 )
-        return;
+        return 0;
 
     hypercall.op     = __HYPERVISOR_mmu_update;
     hypercall.arg[0] = (unsigned long)mmu_updates;
@@ -56,26 +57,31 @@ static void flush_mmu_updates(void)
     if ( mlock(mmu_updates, sizeof(mmu_updates)) != 0 )
     {
         PERROR("Could not lock pagetable update array");
-        exit(1);
+        err = 1;
+        goto out;
     }
 
     if ( do_xen_hypercall(&hypercall) < 0 )
     {
         ERROR("Failure when submitting mmu updates");
-        exit(1);
+        err = 1;
     }
 
     mmu_update_idx = 0;
     
     (void)munlock(mmu_updates, sizeof(mmu_updates));
+
+ out:
+    return err;
 }
 
-static void add_mmu_update(unsigned long ptr, unsigned long val)
+static int add_mmu_update(unsigned long ptr, unsigned long val)
 {
     mmu_updates[mmu_update_idx].ptr = ptr;
     mmu_updates[mmu_update_idx].val = val;
     if ( ++mmu_update_idx == MAX_MMU_UPDATES )
-        flush_mmu_updates();
+        return flush_mmu_updates();
+    return 0;
 }
 
 static int devmem_fd;
@@ -163,9 +169,9 @@ int main(int argc, char **argv)
     }
 
     filename = argv[1];
-    if ( (fd = open(name, O_RDONLY)) == -1 )
+    if ( (fd = open(filename, O_RDONLY)) == -1 )
     {
-        PERROR("Could not open file for writing");
+        PERROR("Could not open state file for reading");
         return 1;
     }
 
@@ -269,8 +275,9 @@ int main(int argc, char **argv)
         {
         case L1TAB:
             memset(ppage, 0, PAGE_SIZE);
-            add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND,
-                           MMUEXT_PIN_L1_TABLE);
+            if ( add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND,
+                                MMUEXT_PIN_L1_TABLE) )
+                goto out;
             for ( j = 0; j < 1024; j++ )
             {
                 if ( page[j] & _PAGE_PRESENT )
@@ -285,17 +292,19 @@ int main(int argc, char **argv)
                         ERROR("Write access requested for a restricted frame");
                         goto out;
                     }
-                    page[j] &= PAGE_SIZE - 1;
+                    page[j] &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PAT);
                     page[j] |= pfn_to_mfn_table[pfn] << PAGE_SHIFT;
                 }
-                add_mmu_update((unsigned long)&ppage[j], page[j]);
+                if ( add_mmu_update((unsigned long)&ppage[j], page[j]) )
+                    goto out;
             }
             break;
         case L2TAB:
             memset(ppage, 0, PAGE_SIZE);
-            add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND,
-                           MMUEXT_PIN_L2_TABLE);
-            for ( j = 0; j < 1024; j++ )
+            if ( add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND,
+                                MMUEXT_PIN_L2_TABLE) )
+                goto out;
+            for ( j = 0; j < (HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT); j++ )
             {
                 if ( page[j] & _PAGE_PRESENT )
                 {
@@ -309,22 +318,35 @@ int main(int argc, char **argv)
                         ERROR("Page table mistyping");
                         goto out;
                     }
-                    page[j] &= PAGE_SIZE - 1;
+                    /* Haven't reached the L1 table yet. Ensure it is safe! */
+                    if ( pfn > i )
+                    {
+                        unsigned long **l1 = map_pfn(pfn_to_mfn_table[pfn]);
+                        memset(l1, 0, PAGE_SIZE);
+                        unmap_pfn(l1);
+                    }
+                    page[j] &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PSE);
                     page[j] |= pfn_to_mfn_table[pfn] << PAGE_SHIFT;
                 }
-                add_mmu_update((unsigned long)&ppage[j], page[j]);
+                if ( add_mmu_update((unsigned long)&ppage[j], page[j]) )
+                    goto out;
             }
             break;
         default:
             memcpy(ppage, page, PAGE_SIZE);
             break;
         }
+        /* NB. Must flush before unmapping page, as pass VAs to Xen. */
+        if ( flush_mmu_updates() )
+            goto out;
         unmap_pfn(ppage);
 
-        add_mmu_update((mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, i);
+        if ( add_mmu_update((mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, i) )
+            goto out;
     }
 
-    flush_mmu_updates();
+    if ( flush_mmu_updates() )
+        goto out;
 
     /* Uncanonicalise the suspend-record frame number and poke resume rec. */
     pfn = ctxt.i386_ctxt.esi;
@@ -391,7 +413,7 @@ int main(int argc, char **argv)
      *  4. fast_trap_idx is checked by Xen.
      *  5. ldt base must be page-aligned, no more than 8192 ents, ...
      *  6. gdt already done, and further checking is done by Xen.
-     *  7. check that ring1_ss/esp is safe.
+     *  7. check that ring1_ss is safe.
      *  8. pt_base is already done.
      *  9. debugregs are checked by Xen.
      *  10. callback code selectors need checking.
@@ -404,8 +426,6 @@ int main(int argc, char **argv)
     }
     if ( (ctxt.ring1_ss & 3) == 0 )
         ctxt.ring1_ss = FLAT_RING1_DS;
-    if ( ctxt.ring1_esp > HYPERVISOR_VIRT_START )
-        ctxt.ring1_esp = HYPERVISOR_VIRT_START;
     if ( (ctxt.event_callback_cs & 3) == 0 )
         ctxt.event_callback_cs = FLAT_RING1_CS;
     if ( (ctxt.failsafe_callback_cs & 3) == 0 )
@@ -419,9 +439,11 @@ int main(int argc, char **argv)
         goto out;
     }
 
-
-    /* Success! */
-    rc = 0;
+    op.cmd = DOM0_BUILDDOMAIN;
+    op.u.builddomain.domain   = dom;
+    op.u.builddomain.num_vifs = 1;
+    memcpy(&op.u.builddomain.ctxt, &ctxt, sizeof(ctxt));
+    rc = do_dom0_op(&op);
 
  out:
     /* If we experience an error then kill the half-constructed domain. */
index 1716d04eb6637bfe8bec9c17efac7e22130f8f4c..54d0a405503a77c4ec1a2f4010fef0e17a63f973 100644 (file)
@@ -98,7 +98,7 @@ static int checked_write(int fd, const void *buf, size_t count)
 int main(int argc, char **argv)
 {
     dom0_op_t op;
-    int rc = 1, i;
+    int rc = 1, i, j;
     unsigned long mfn, dom;
 
     /* Remember if we stopped the guest, so we can restart it on exit. */
@@ -148,7 +148,7 @@ int main(int argc, char **argv)
     }
 
     filename = argv[2];
-    if ( (fd = open(name, O_CREAT|O_EXCL|O_RDWR)) == -1 )
+    if ( (fd = open(filename, O_CREAT|O_EXCL|O_WRONLY, 0644)) == -1 )
     {
         PERROR("Could not open file for writing");
         return 1;
@@ -255,15 +255,14 @@ int main(int argc, char **argv)
             goto out;
         }
 
-        pfn_to_mfn_table[i] = mfn;
-
         /* Did we map this MFN already? That would be invalid! */
         if ( MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )
         {
             ERROR("A machine frame appears twice in pseudophys space");
             goto out;
         }
-        
+
+        pfn_to_mfn_table[i] = mfn;
         mfn_to_pfn_table[mfn] = i;
 
         /* Query page type by MFN, but store it by PFN. */
@@ -331,17 +330,20 @@ int main(int argc, char **argv)
 
         if ( (pfn_type[i] == L1TAB) || (pfn_type[i] == L2TAB) )
         {
-            for ( i = 0; i < 1024; i++ )
+            for ( j = 0; 
+                  j < ((pfn_type[i] == L2TAB) ? 
+                       (HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT) : 1024); 
+                  j++ )
             {
-                if ( !(page[i] & _PAGE_PRESENT) ) continue;
-                mfn = page[i] >> PAGE_SHIFT;
+                if ( !(page[j] & _PAGE_PRESENT) ) continue;
+                mfn = page[j] >> PAGE_SHIFT;
                 if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )
                 {
                     ERROR("Frame number in pagetable page is invalid");
                     goto out;
                 }
-                page[i] &= PAGE_SIZE - 1;
-                page[i] |= mfn_to_pfn_table[mfn] << PAGE_SHIFT;
+                page[j] &= PAGE_SIZE - 1;
+                page[j] |= mfn_to_pfn_table[mfn] << PAGE_SHIFT;
             }
         }
 
index 61221c20a130e95c0c2cbaac7ab736523e57ae2d..0546f53582790be837c515f34241fd4f0acdf35e 100644 (file)
@@ -129,7 +129,8 @@ long do_stack_switch(unsigned long ss, unsigned long esp)
     int nr = smp_processor_id();
     struct tss_struct *t = &init_tss[nr];
 
-    if ( ((ss & 3) == 0) || (esp > HYPERVISOR_VIRT_START) )
+    /* We need to do this check as we load and use SS on guest's behalf. */
+    if ( (ss & 3) == 0 )
         return -EPERM;
 
     current->thread.ss1  = ss;
index 05bbe1ea92c51e139f53eca0815896a8c6948f13..4dc4b43e03783466c2f1ba3dc6f2451149252c79 100644 (file)
@@ -248,7 +248,7 @@ void switch_to(struct task_struct *prev_p, struct task_struct *next_p)
      * then we'll #GP.
      */
     if ( (stack_ec->cs & 3) == 0 )
-        stack_ec->cs = 0;
+        stack_ec->cs = FLAT_RING1_CS;
 
     unlazy_fpu(prev_p);
 
index 1668a13b5641a4c63921fa3f8ebd6d9b1c697680..330defe3a8b8c0c23ae9796b1f56cfcf29cc9c29 100644 (file)
@@ -292,14 +292,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, long error_code)
 
     __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : );
 
-    if ( unlikely(!(regs->xcs & 3)) )
-        goto fault_in_hypervisor;
-
     if ( unlikely(addr > PAGE_OFFSET) )
         goto fault_in_xen_space;
 
  propagate_fault:
 
+    if ( unlikely(!(regs->xcs & 3)) )
+        goto fault_in_hypervisor;
+
     ti = p->thread.traps + 14;
     gtb->flags = GTBF_TRAP_CR2; /* page fault pushes %cr2 */
     gtb->cr2        = addr;
index 16291189297e12d15564019bb6f5d51bb434469f..8d33bd9f2088448621c099e35e158dfe3fe9357b 100644 (file)
@@ -408,17 +408,17 @@ static int get_l2_table(unsigned long page_nr)
     {
         l2_entry = *p_l2_entry++;
         if ( !(l2_pgentry_val(l2_entry) & _PAGE_PRESENT) ) continue;
-        if ( (l2_pgentry_val(l2_entry) & (_PAGE_GLOBAL|_PAGE_PSE)) )
+        if ( unlikely((l2_pgentry_val(l2_entry) & (_PAGE_GLOBAL|_PAGE_PSE))) )
         {
             MEM_LOG("Bad L2 page type settings %04lx",
                     l2_pgentry_val(l2_entry) & (_PAGE_GLOBAL|_PAGE_PSE));
             ret = -1;
-            goto out;
+            goto fail;
         }
         /* Assume we're mapping an L1 table, falling back to twisted L2. */
         ret = get_l1_table(l2_pgentry_to_pagenr(l2_entry));
-        if ( ret ) ret = get_twisted_l2_table(page_nr, l2_entry);
-        if ( ret ) goto out;
+        if ( unlikely(ret) ) ret = get_twisted_l2_table(page_nr, l2_entry);
+        if ( unlikely(ret) ) goto fail;
     }
     
     /* Now we simply slap in our high mapping. */
@@ -435,6 +435,18 @@ static int get_l2_table(unsigned long page_nr)
  out:
     unmap_domain_mem(p_l2_entry);
     return ret;
+
+ fail:
+    p_l2_entry--;
+    while ( i-- > 0 )
+    {
+        l2_entry = *--p_l2_entry;
+        if ( (l2_pgentry_val(l2_entry) & _PAGE_PRESENT) )
+            put_l1_table(l2_pgentry_to_pagenr(l2_entry));
+    }
+    if ( dec_page_refcnt(page_nr, PGT_l2_page_table) != 0 )
+        BUG();
+    goto out;
 }
 
 
@@ -453,24 +465,38 @@ static int get_l1_table(unsigned long page_nr)
     {
         l1_entry = *p_l1_entry++;
         if ( !(l1_pgentry_val(l1_entry) & _PAGE_PRESENT) ) continue;
-        if ( (l1_pgentry_val(l1_entry) &
-              (_PAGE_GLOBAL|_PAGE_PAT)) )
+        if ( unlikely((l1_pgentry_val(l1_entry) &
+                       (_PAGE_GLOBAL|_PAGE_PAT))) )
         {
             MEM_LOG("Bad L1 page type settings %04lx",
                     l1_pgentry_val(l1_entry) &
                     (_PAGE_GLOBAL|_PAGE_PAT));
             ret = -1;
-            goto out;
+            goto fail;
         }
         ret = get_page(l1_pgentry_to_pagenr(l1_entry),
                        l1_pgentry_val(l1_entry) & _PAGE_RW);
-        if ( ret ) goto out;
+        if ( unlikely(ret) ) goto fail;
     }
 
  out:
     /* Make sure we unmap the right page! */
     unmap_domain_mem(p_l1_entry-1);
     return ret;
+
+ fail:
+    p_l1_entry--;
+    while ( i-- > 0 )
+    {
+        l1_entry = *--p_l1_entry;
+        if ( (l1_pgentry_val(l1_entry) & _PAGE_PRESENT) ) 
+            put_page(l1_pgentry_to_pagenr(l1_entry), 
+                     l1_pgentry_val(l1_entry) & _PAGE_RW);
+    }
+    if ( dec_page_refcnt(page_nr, PGT_l1_page_table) != 0 )
+        BUG();
+    unmap_domain_mem(p_l1_entry);
+    return ret;
 }
 
 
@@ -550,10 +576,8 @@ static void put_l1_table(unsigned long page_nr)
     {
         l1_entry = *p_l1_entry++;
         if ( (l1_pgentry_val(l1_entry) & _PAGE_PRESENT) ) 
-        {
             put_page(l1_pgentry_to_pagenr(l1_entry), 
                      l1_pgentry_val(l1_entry) & _PAGE_RW);
-        }
     }
 
     /* Make sure we unmap the right page! */
@@ -611,9 +635,6 @@ static int mod_l2_entry(l2_pgentry_t *p_l2_entry, l2_pgentry_t new_l2_entry)
         if ( ((l2_pgentry_val(old_l2_entry) ^ 
                l2_pgentry_val(new_l2_entry)) & 0xfffff001) != 0 )
         {
-            if ( (l2_pgentry_val(old_l2_entry) & _PAGE_PRESENT) ) 
-                put_l1_table(l2_pgentry_to_pagenr(old_l2_entry));
-            
             /* Assume we're mapping an L1 table, falling back to twisted L2. */
             if ( unlikely(get_l1_table(l2_pgentry_to_pagenr(new_l2_entry))) )
             {
@@ -623,6 +644,9 @@ static int mod_l2_entry(l2_pgentry_t *p_l2_entry, l2_pgentry_t new_l2_entry)
                 if ( get_twisted_l2_table(l1e >> PAGE_SHIFT, new_l2_entry) )
                     goto fail;
             }
+
+            if ( (l2_pgentry_val(old_l2_entry) & _PAGE_PRESENT) ) 
+                put_l1_table(l2_pgentry_to_pagenr(old_l2_entry));            
         } 
     }
     else if ( (l2_pgentry_val(old_l2_entry) & _PAGE_PRESENT) )
@@ -659,13 +683,13 @@ static int mod_l1_entry(l1_pgentry_t *p_l1_entry, l1_pgentry_t new_l1_entry)
         if ( ((l1_pgentry_val(old_l1_entry) ^
                l1_pgentry_val(new_l1_entry)) & 0xfffff003) != 0 )
         {
-            if ( (l1_pgentry_val(old_l1_entry) & _PAGE_PRESENT) ) 
-                put_page(l1_pgentry_to_pagenr(old_l1_entry),
-                         l1_pgentry_val(old_l1_entry) & _PAGE_RW);
-
             if ( get_page(l1_pgentry_to_pagenr(new_l1_entry),
                           l1_pgentry_val(new_l1_entry) & _PAGE_RW) )
                 goto fail;
+
+            if ( (l1_pgentry_val(old_l1_entry) & _PAGE_PRESENT) ) 
+                put_page(l1_pgentry_to_pagenr(old_l1_entry),
+                         l1_pgentry_val(old_l1_entry) & _PAGE_RW);
         } 
     }
     else if ( (l1_pgentry_val(old_l1_entry) & _PAGE_PRESENT) )
@@ -696,10 +720,24 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
     switch ( cmd )
     {
     case MMUEXT_PIN_L1_TABLE:
+        if ( unlikely(page->type_count & REFCNT_PIN_BIT) )
+        {
+            MEM_LOG("Pfn %08lx already pinned", pfn);
+            err = 1;
+            break;
+        }
         err = get_l1_table(pfn);
         goto mark_as_pinned;
+
     case MMUEXT_PIN_L2_TABLE:
+        if ( unlikely(page->type_count & REFCNT_PIN_BIT) )
+        {
+            MEM_LOG("Pfn %08lx already pinned", pfn);
+            err = 1;
+            break;
+        }
         err = get_l2_table(pfn);
+
     mark_as_pinned:
         if ( unlikely(err) )
         {
@@ -708,16 +746,8 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
         }
         put_page_type(page);
         put_page_tot(page);
-        if ( likely(!(page->type_count & REFCNT_PIN_BIT)) )
-        {
-            page->type_count |= REFCNT_PIN_BIT;
-            page->tot_count  |= REFCNT_PIN_BIT;
-        }
-        else
-        {
-            MEM_LOG("Pfn %08lx already pinned", pfn);
-            err = 1;
-        }
+        page->type_count |= REFCNT_PIN_BIT;
+        page->tot_count  |= REFCNT_PIN_BIT;
         break;
 
     case MMUEXT_UNPIN_TABLE:
@@ -805,7 +835,7 @@ int do_mmu_update(mmu_update_t *ureqs, int count)
     mmu_update_t req;
     unsigned long flags, pfn, l1e;
     struct pfn_info *page;
-    int err = 0, i, cpu = smp_processor_id();
+    int rc = 0, err = 0, i, cpu = smp_processor_id();
     unsigned int cmd;
     unsigned long cr0 = 0;
 
@@ -814,11 +844,10 @@ int do_mmu_update(mmu_update_t *ureqs, int count)
 
     for ( i = 0; i < count; i++ )
     {
-
         if ( unlikely(copy_from_user(&req, ureqs, sizeof(req)) != 0) )
         {
-            if ( cr0 != 0 ) write_cr0(cr0);
-            kill_domain_with_errmsg("Cannot read page update request");
+            rc = -EFAULT;
+            break;
         }
 
         cmd = req.ptr & (sizeof(l1_pgentry_t)-1);
@@ -939,8 +968,8 @@ int do_mmu_update(mmu_update_t *ureqs, int count)
 
         if ( unlikely(err) )
         {
-            if ( cr0 != 0 ) write_cr0(cr0);
-            kill_domain_with_errmsg("Illegal page update request");
+            rc = -EINVAL;
+            break;
         }
 
         ureqs++;
@@ -961,7 +990,7 @@ int do_mmu_update(mmu_update_t *ureqs, int count)
     if ( cr0 != 0 )
         write_cr0(cr0);
 
-    return 0;
+    return rc;
 }
 
 
@@ -991,11 +1020,11 @@ int do_update_va_mapping(unsigned long page_nr,
         write_cr0(cr0 & ~X86_CR0_WP);        
     }
 
-    if ( unlikely((err = mod_l1_entry(&linear_pg_table[page_nr], 
-                                      mk_l1_pgentry(val))) != 0) )
+    if ( unlikely(mod_l1_entry(&linear_pg_table[page_nr], 
+                               mk_l1_pgentry(val)) != 0) )
     {
-        spin_unlock_irq(&p->page_lock);
-        kill_domain_with_errmsg("Illegal VA-mapping update request");
+        err = -EINVAL;
+        goto check_cr0_unlock_and_out;
     }
 
     if ( unlikely(flags & UVMF_INVLPG) )
@@ -1004,9 +1033,9 @@ int do_update_va_mapping(unsigned long page_nr,
     if ( unlikely(flags & UVMF_FLUSH_TLB) )
         __write_cr3_counted(pagetable_val(p->mm.pagetable));
 
+ check_cr0_unlock_and_out:
     if ( unlikely(cr0 != 0) )
         write_cr0(cr0);
-
  unlock_and_out:
     spin_unlock_irq(&p->page_lock);
  out:
index ae7c587eabdb91bbba51a0b0ecb58739f7d324ed..22366631207674b1570fc4c23f0356a454066429 100644 (file)
@@ -155,8 +155,7 @@ static void __init parse_mem_cmdline (char ** cmdline_p)
 
 void __init setup_arch(char **cmdline_p)
 {
-    unsigned long start_pfn, max_pfn, max_low_pfn;
-    unsigned long bootmap_size;
+    unsigned long bootmap_size, start_pfn, max_low_pfn;
     unsigned long i;
 
     extern void hypervisor_callback(void);
index 08bc1faf6b9136cb37ca7ed40e29bd211cfec11e..0fbf40c951a0091b2b95793ea2f7c3166b1e6229 100644 (file)
@@ -10,6 +10,7 @@
 #define __HYPERVISOR_H__
 
 #include <linux/types.h>
+#include <linux/kernel.h>
 #include <asm/hypervisor-ifs/hypervisor-if.h>
 #include <asm/hypervisor-ifs/dom0_ops.h>
 #include <asm/ptrace.h>
@@ -167,6 +168,9 @@ static inline int HYPERVISOR_mmu_update(mmu_update_t *req, int count)
         : "=a" (ret) : "0" (__HYPERVISOR_mmu_update), 
         "b" (req), "c" (count) );
 
+    if ( unlikely(ret < 0) )
+        panic("Failed mmu update: %p, %d", req, count);
+
     return ret;
 }
 
@@ -396,6 +400,10 @@ static inline int HYPERVISOR_update_va_mapping(
         : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping), 
         "b" (page_nr), "c" ((new_val).pte_low), "d" (flags) );
 
+    if ( unlikely(ret < 0) )
+        panic("Failed update VA mapping: %08lx, %08lx, %08lx",
+              page_nr, (new_val).pte_low, flags);
+    
     return ret;
 }